// 这里书写 xhl 项目的打包内容

// 0. 导入 gulp 第三方
const gulp = require('gulp')
// 0-2. 导入 gulp-cssmin
const cssmin = require('gulp-cssmin')
// 0-3. 导入 gulp-autoprefixer
const autoprefixer = require('gulp-autoprefixer')
// 0-4. 导入 gulp-uglify
const uglify = require('gulp-uglify')
// 0-5. 导入 gulp-babel
const babel = require('gulp-babel')
// 0-6. 导入 gulp-sass
// const sass = require('gulp-sass')(require('sass'))
// 0-7. 导入 gulp-htmlmin
const htmlmin = require('gulp-htmlmin')
// 0-8. 导入 gulp-imagemin
// const imagemin = require('gulp-imagemin')
// // 0-9. 导入 del
// const del = require('del')
// // 0-10. 导入 gulp-webserver
// const webserver = require('gulp-webserver')

/*
  1. 配置打包 css 的任务
    + 如何打包 css 文件 ?
    + 有一个第三方包, 专门用来去除 css 文件中的空格的
    + 叫做 gulp-cssmin
    + 下载: $ npm i -D gulp-cssmin
    + 导入: const cssmin = require('gulp-cssmin')
    + 导入以后得到的是一个函数, 直接调用就可以了
    + 在 gulpfile 内把 cssHandler 这个任务进行导出
      => 导出以后, 就可以在命令行利用 gulp 工具来执行这个任务了
      => 打开命令行, 目录切换到项目根目录
      => 输入指令: $ gulp 任务名称
    + 解决一个报错:
      => 因为 gulp 工具捕获不到 cssHandler 任务的完成
      => 并不是不能完成, 只是 gulp 不知道他什么时候完成的
      => 因为 gulp 工具没有得到 gulp 的工作流
      => 只要写一个 return 就可以了

  扩展: 自动添加前缀
    + 问题: 压缩之前做, 还是之后做 ?
      => 先找到文件, 自动添加前缀, 把添加完前缀的压缩
    + 自动添加前缀有一个第三方包
      => 叫做 gulp-autoprefixer
      => 下载: $ npm i -D gulp-autoprefixer
      => 导入: const autoprefixer = require('gulp-autoprefixer')
      => 导入以后: 就是一个函数, 直接调用
        -> 但是需要传递一个参数, 表示你要兼容的是那些浏览器
        -> { browsers: ['', ''] }
        -> 最好是把参数替换到 package.json 文件中
*/

// 1-1. 创建一个 打包 css 的任务
// 问题: 打包 css 和 打包 js 有没有可能是一样的 ?
// 打包一种文件, 就需要一个任务
// 将来你执行 cssHandler 的时候, 就是在执行对应的函数
const cssHandler = () => {
  // 1-2. 找到源文件
  // 你要打包的是 ./src/js 文件夹里面的内容吗 ?
  // 你要打包的是 ./src/images 文件夹里面的内容吗 ?
  return gulp
    .src('./src/css/*.css') // 找到文件
    .pipe(autoprefixer()) // 自动添加前缀
    .pipe(cssmin()) // 打包
    .pipe(gulp.dest('./dist/css/')) // 放到指定目录内
}

/*
  2. 打包 js 文件
    + 压缩 js 文件使用一个第三方包, 叫做 gulp-uglify
    + 下载: $ npm i -D gulp-uglify
    + 导入: const uglify = require('gulp-uglify')
    + 导入以后, 得到一个函数, 直接调用就可以了

  需要做一个转码, 把 es6 转换为 es5
    + 问题: 什么时候进行转码操作 ?
      => 找到文件之后, 先进行转码, 再进行压缩
    + 使用一个第三方包进行转换, 叫做 gulp-babel
      => 注意: 因为 gulp-babel 依赖了另外两个包
        -> 但是他自己不会下载
        -> 我们需要手动把另外两个包也下载下来
        -> 一个叫做 @babel/core
        -> 一个叫做 @babel/preset-env
    + 下载:
      => $ npm i -D gulp-babel
      => $ npm i -D @babel/core
      => $ npm i -D @babel/preset-env
    + 导入: const babel = require('gulp-babel')
    + 导入以后, 得到的就是一个函数, 调用函数的时候传递参数就可以进行 es6 转换 es5 了
      => 传递的参数是一个 { presets: ['@babel/preset-env'] }

  总结: 对于 js 的打包任务
    + 下载:
      => gulp-uglify   用于压缩
      => gulp-babel    用于转码
      => @babel/core   用于 babel 依赖
      => @babel/preset-env  用于 babel 依赖
    + 导入:
      => const uglify = require('gulp-uglify')
      => const babel = require('gulp-babel')
    + 使用:
      => uglify()
      => babel({ prestes: ['@babel/preset-env'] })
*/

// 2-1. 创建一个 打包 js 的任务
const jsHandler = () => {
  // 2-2. 找到指定的 js 文件
  return gulp
    .src('./src/js/*.js') // 找到指定的 js 文件
    .pipe(babel({ presets: ['@babel/preset-env'] })) // 进行 es6 转换 es5
    .pipe(uglify()) // 对 js 代码进行压缩
    .pipe(gulp.dest('./dist/js/')) // 放到指定目录内
}

/*
  3. 打包 sass 的任务
    + 和 打包 css 的任务有什么区别 ?
      => 就多了一个过程, 就是把 sass 转换成 css
    + 什么时候转换 ?
      => 获取到指定文件
      => 先把 sass 转换成 css
      => 然后自动添加前缀
      => 然后压缩代码
      => 然后放在指定目录内
    + 把 sass 转换成 css 需要用到一个第三方包, 叫做 gulp-sass
      =>  特别说明
        -> 当你下载 gulp-sass 的时候, 大概率会失败
        -> 因为 gulp-sass 依赖了一个第三方包叫做 node-sass
        -> 因为 gulp-sass 还需要依赖一个叫做 sass 的包
        -> 会自己下载, 但是 node-sass 的下载很容易失败
        -> 手动下载一下 node-sass
      => 导入的时候
        -> const sass = require('gulp-sass')(require('sass'))

  总结: 最新版本的 gulp-sass 包 5.x
    + 下载:
      => $ npm i -D gulp-sass
      => $ npm i -D node-sass
      => $ npm i -D sass
    + 下载 node-sass 会大概率失败
      => 下载失败的时候, 执行下面这句代码
      => 临时把 node-sass 的下载地址切换
      => $ set SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/
      => 再次尝试下载就好了
    + 导入:
      => 只需要导入一个 gulp-sass
      => 语法: const sass = require('gulp-sass')(require('sass'))
    + 使用:
      => sass()
*/

// 3-1. 创建一个打包 sass 的任务
// const sassHandler = () => {
//   // 3-2. 找到指定的文件
//   return gulp
//     .src('./src/sass/*.scss')
//     .pipe(sass())
//     .pipe(autoprefixer())
//     .pipe(cssmin())
//     .pipe(gulp.dest('./dist/sass/'))
// }

/*
  4. 打包 html 的任务
    + 压缩 html 需要用到一个第三方包, 叫做 gulp-htmlmin
    + 下载: $ npm i -D gul-htmlmin
    + 导入: const htmlmin = require('gulp-htmlmin')
    + 导入以后得到一个函数, 直接调用, 需要传递参数来实现
      => 如果你不传递参数, 不会进行任何压缩操作
*/
// 4-1. 创建一个打包 html 文件的任务
const htmlHandler = () => {
  // 4-2. 找到指定的文件
  return gulp
    .src('./src/views/*.html')
    .pipe(htmlmin({
      // 去掉所有的空格空白内容
      collapseWhitespace: true,
      // 去掉布尔类型属性
      collapseBooleanAttributes: true,
      // 移出属性值位置的双引号
      removeAttributeQuotes: true,
      // 移出注释内容
      removeComments: true,
      // 移出空属性
      removeEmptyAttributes: true,
      // 移出 script 标签上的默认 type 属性
      removeScriptTypeAttributes: true,
      // 移出 style 标签和 link 标签的 默认 type 属性
      removeStyleLinkTypeAttributes: true,
      // 压缩内嵌式 js 代码
      // 注意: 不能包含 es6 语法
      minifyJS: true,
      // 压缩内嵌式 css 样式
      minifyCSS: true
    })) // 进行压缩
    .pipe(gulp.dest('./dist/views/')) // 放到指定目录
}


/*
  5. 打包 images 的任务
    + 压缩图片需要使用一个第三方包叫做 gulp-imagemin
    + 下载: $ npm i -D gulp-imagemin
    + 导入: const imagemin = require('gulp-imagemin')
*/

// 5-1. 创建一个打包 image 的任务
const imgHandler = () => {
  // 5-2. 找到指定内容
  return gulp
    .src('./src/images/*.**')
    // .pipe(imagemin())
    .pipe(gulp.dest('./dist/images/'))
}

/*
  6. 一些内容的转移任务
    + 遇到视音频都是直接转移
*/
const audioHandler = () => {
  return gulp
    .src('./src/audios/*.**')
    .pipe(gulp.dest('./dist/audio/'))
}

const videoHandler = () => {
  return gulp
    .src('./src/videos/*.**')
    .pipe(gulp.dest('./dist/videos/'))
}

// fonts 直接转移
const fontHandler = () => {
  return gulp
    .src('./src/fonts/*.**')
    .pipe(gulp.dest('./dist/fonts/'))
}

// data 直接转移
const dataHandler = () => {
  return gulp
    .src('./src/data/*.**')
    .pipe(gulp.dest('./dist/data/'))
}

// vendor 直接转移
const vendorHandler = () => {
  return gulp
    .src('./src/vendor/*.**')
    .pipe(gulp.dest('./dist/vendor/'))
}

/*
  7. 配置一个 删除 dist 文件的任务
    + 删除文件夹需要用到一个第三方包叫做 del
    + 下载: $ npm i -D del
    + 导入: const del = require('del')
    + 导入以后得到的就是一个 函数
      => 直接调用 del(['要删除的文件夹名称'])
    + 需要把这个任务加到 默认任务中
      => 是否需要和其他任务有顺序关系
*/

// const delHandler = () => {
//   return del(['./dist/'])
// }

/*
  8. 配置一个启动临时服务器的任务
    + 配置启动服务器需要用到一个包叫做 gulp-webserver
    + 下载: $ npm i -D gulp-webserver
    + 导入: const webserver = requrie('gulp-webserver')
    + 导入以后得到一个函数, 需要配置一些信息
    + 问题: 如果你打开页面查看, 应该是看 dist 里面的html 文件
            还是查看 src 目录下的 html 文件
*/
// const serverHandler = () => {
//   // 找到目录
//   return gulp
//     .src('./dist/')
//     .pipe(webserver({  // 开启服务器
//       // 域名
//       host: 'www.xhl.com',
//       // 端口号
//       port: 3030,
//       // 默认自动打开哪一个文件, 路径从 dist 以后开始书写就行
//       open: './views/a.html',
//       // 自动刷新, 当代码发生变化的时候, 自动刷新浏览器
//       livereload: true,
//       // 配置服务器代理
//       proxies: [
//         // 一个代理就是一个对象
//         {
//           // 代理标识符
//           source: '/guoxiang',
//           // 目标地址
//           target: 'http://localhost:8080/test.php'
//         }
//       ]
//     }))
// }

/*
  webserver 的时候, host 位置可以书写自定义域名
    1. host 确定好你要用的域名(尽量不要用一些大众的域名)
    2. 进行 系统 hosts 文件的配置
      => OS: command + g -> 输入 /etc 回车
      => win: 我的电脑 -> 系统盘符 -> windows -> system32 -> drivers -> etc
      => 找到一个叫做 hosts 的文件(注意这个文件只有名字没有后缀)
*/


/*
  9. 配置一个监控任务
    + 当文件发生变化的时候, 能够从新执行进行打包操作
*/

// const watchHandler = () => {
//   // 用于监控变化
//   gulp.watch('./src/css/*.css', cssHandler)
//   gulp.watch('./src/views/*.html', htmlHandler)
//   gulp.watch('./src/js/*.js', jsHandler)
// }

/*
  倒是第二. 配置一个默认任务
    + 作用: 能帮我把其他任务调动起来
*/

// 创建一个默认任务
// 需要把其他的一些任务一起执行掉
// 使用 gulp.parallel 来实现并行
// 语法: gulp.parallel(任务1, 任务2, 任务3, ...)
// 返回值, 就是一个函数, 直接赋值给 _default
// const res = gulp.parallel(cssHandler, jsHandler, htmlHandler, sassHandler, imgHandler, videoHandler, audioHandler, dataHandler, fontHandler, vendorHandler)

// 当你导出了一个任务叫做 default 的时候
// 你在使用 gulp default 这个指令的时候
// 可以简写, 直接写 gulp
// 默认会自动执行一个叫做 default 的 任务
// const _default = gulp.series(
//   delHandler,
//   res,
//   serverHandler,
//   watchHandler
// )

// end, 把准备好的任务导出
module.exports = {
  cssHandler: cssHandler,
  jsHandler: jsHandler,
  // sassHandler: sassHandler,
  htmlHandler: htmlHandler,
  imgHandler: imgHandler,
  audioHandler: audioHandler,
  videoHandler: videoHandler,
  fontHandler: fontHandler,
  dataHandler: dataHandler,
  vendorHandler: vendorHandler,
  // delHandler: delHandler,
  // default: _default,
}
